﻿<template>
    <div v-bind="$attrs" style="border:1px solid #ccc;">
        <template v-if="oneGroup">
            <el-select v-model="cgroup" style="width: 100%; padding: 4px;">
                <el-option label="--请选择分类--" value=""></el-option>
                <el-option v-for="group in groups" :key="group" :label="group[cfg.groupKey]"
                    :value="group[cfg.groupKey]"></el-option>
            </el-select>
        </template>
        <template v-if="showAsTable">
            <table class="pure-table" style="width:100%;">
                <tbody>
                    <template v-for="group in groups2" :key="group">
                        <template v-if="groupSingleLine">
                            <tr v-for="(item, ix) in group.children" :key="item">
                                <th style="text-align:left" v-if="ix == 0" :colspan="SingleGroupColCount">{{
                                    group[cfg.groupKey]
                                }}
                                </th>
                            </tr>
                            <tr v-for="(item) in group.children" :key="item">
                                <td :style="{ 'text-align': itemAlign }">{{ item[cfg.labelKey] }}</td>
                                <td>
                                    <el-icon :size="checkSize" @click="clickItem(item)">
                                        <Select color="green" v-if="item[cfg.checkKey] == true" />
                                        <CloseBold color="red" v-if="item[cfg.checkKey] == false" />
                                    </el-icon>
                                </td>
                                <td v-if="cfg.remarkField">
                                    <TextImageEditor v-model="item[cfg.remarkField]" :title="item[cfg.labelKey]"
                                        :disabled="disabled" typeOf="text" />
                                </td>
                                <td v-if="cfg.photoField">
                                    <TextImageEditor v-model="item[cfg.photoField]" :title="item[cfg.labelKey]"
                                        :disabled="disabled" typeOf="image" />
                                </td>
                            </tr>
                        </template>
                        <template v-else>
                            <tr v-for="(item, ix) in group.children" :key="item">
                                <td style="vertical-align: middle;" v-if="ix == 0" :rowspan="group.children.length">
                                    {{ group[cfg.groupKey] }}</td>
                                <td :style="{ 'text-align': itemAlign }">{{ item[cfg.labelKey] }}</td>
                                <td>
                                    <el-icon :size="checkSize" @click="clickItem(item)">
                                        <Check v-if="item[cfg.checkKey]" />
                                    </el-icon>
                                </td>
                                <td v-if="cfg.remarkField">
                                    <TextImageEditor v-model="item[cfg.remarkField]" :title="item[cfg.labelKey]"
                                        :disabled="disabled" typeOf="text" />
                                </td>
                                <td v-if="cfg.photoField">
                                    <TextImageEditor v-model="item[cfg.photoField]" :title="item[cfg.labelKey]"
                                        :disabled="disabled" typeOf="image" />
                                </td>
                            </tr>
                        </template>
                    </template>
                </tbody>
            </table>
        </template>

        <template v-else>
            <div style="overflow:auto;">
                <div class="group" v-for="group in groups2" :key="group">
                    <div class="group-title">
                        <el-checkbox :disabled="disabled" v-model="checkAll[group[cfg.groupKey]]"
                            @change="groupClickAll(group, $event)" :label="group[cfg.groupKey]"
                            :indeterminate="isIndeterminate(group)"></el-checkbox>
                    </div>
                    <div class="group-box">
                        <div class="group-item" v-for="item in group.children" :key="item">
                            <el-checkbox :disabled="disabled" v-model="item[cfg.checkKey]"
                                :label="item[cfg.labelKey]"></el-checkbox>
                        </div>
                    </div>
                </div>
            </div>
        </template>
    </div>
</template>

<script>
import { Select, CloseBold } from '@element-plus/icons-vue'


export default {
    name: "GroupCheckList",
    components: { Select, CloseBold },
    emits: ["update:modelValue"],
    props: {
        modelValue: {
            type: Array,
            default: []
        },
        disabled: {
            type: Boolean,
            default: false
        },
        cfg: Object,
        showAsTable: Boolean,
        oneGroup: Boolean,
        groupSingleLine: Boolean,
        itemAlign: {
            type: String,
            default: "center"
        },
        checkSize: {
            type: Number,
            default: 24
        },
    },
    data() {
        return {
            checkAll: [],
            groups: [],
            records: null,
            cgroup: "",
        }
    },
    created() {
        if (this.cfg != null) {
            this.loadCfg();
        }
    },
    methods: {
        loadCfg() {
            if (!this.cfg || this.records) return;
            //cfg:{
            // tbname,   数据来源表， 例如：检查项目表，初始检查表格从此构建， 否则从modelValue中恢复
            // search,   检索条件
            // idKey     
            // groupKey, 分组字段名   例如：检查项目分类
            // labelKey, 项目字段名   例如：检查项目名称
            // checkKey, 项目检查字段名  例如：检查项目的检查结果
            // srcFields 来源字段
            // dstFields 目标字段
            //}
            if (this.cfg.tbname) {
                this.$server.getDM(this.cfg.tbname).then(tb => {
                    return this.$server.list(this.cfg.tbname, 1, 1000, this.cfg.search).then(res => {
                        this.records = (res.records);
                        return this.records;
                    })
                }).then(res => {
                    this.loadData();
                }).then(() => {
                    this.makeGroup(this.modelValue);
                })
            } else {
                this.makeGroup(this.modelValue);
            }
        },
        loadData() {
            if (!this.records) return;
            if (!this.cfg.srcFields || !this.cfg.dstFields) return;

            const srcFields = this.cfg.srcFields.split(",").filter(p => p.length > 0);
            const dstFields = this.cfg.dstFields.split(",").filter(p => p.length > 0);
            const items = this.records.map(p => {
                const item = {};
                for (let ix = 0; ix < srcFields.length; ix++) {
                    const srcKey = srcFields[ix];
                    const dstKey = dstFields[ix];
                    item[dstKey] = p[srcKey];
                }
                return item;
            });
            if (!this.modelValue || this.modelValue.length == 0) {
                this.$emit("update:modelValue", items);
            }
        },
        makeGroup(val) {
            if (!val || val.length == 0) {
                this.groups = [];
                this.cgroup = "";
                this.loadData();
                return;
            }
            if (this.tbname && (!this.records || !Array.isArray(this.records))) return;

            const groupKey = this.cfg.groupKey;
            const a1 = val.map(p => p[groupKey]);

            const a2 = a1.reduce((newArray, p) => {
                if (newArray.indexOf(p) == -1) {
                    newArray.push(p);
                }
                return newArray;
            }, []);

            const a3 = a2.map(p => {
                let item = {};
                item[groupKey] = p;
                item.children = val.filter(p1 => p1[groupKey] == p);
                if (this.records && Array.isArray(this.records)) {
                    item.children = item.children.map(p2 => {
                        let p3 = this.records.find(p3 => p3.ID == p2[this.cfg.idKey]);
                        if (p3) {
                            p2[this.cfg.labelKey] = p3[this.cfg.labelKey] || p2[this.cfg.labelKey];
                        }
                        return p2;
                    });
                }
                return item;
            })

            this.groups = a3;
            this.cgroup = a3.length > 0 ? a3[0][this.cfg.groupKey] : "";
        },
        groupClickAll(group, check) {
            //check是点击时状态，
            group.children.forEach(p => {
                p[this.cfg.checkKey] = !check;
            })
        },
        isIndeterminate(group) {
            let checkCount = group.children.filter(p => p[this.cfg.checkKey] == true).length;
            this.checkAll[group[this.cfg.groupKey]] = checkCount == group.children.length;
            return checkCount > 0 && checkCount < group.children.length;
        },
        clickItem(item) {
            if (this.disabled) return;
            item[this.cfg.checkKey] = !item[this.cfg.checkKey];
        }
    },
    computed: {
        SingleGroupColCount() {
            return 2 + (this.cfg.photoField ? 1 : 0) + (this.cfg.remarkField ? 1 : 0);
        },
        groups2() {
            if (this.oneGroup && this.cgroup) {
                return this.groups.filter(x => x[this.cfg.groupKey] == this.cgroup);
            }
            return this.groups;
        }
    },
    watch: {
        cfg() {
            this.loadCfg();
        },
        modelValue(val) {
            if (val) {
                this.makeGroup(val);
            }
        }
    }
}

</script>

<style scoped>
.group {
    overflow: auto;
    padding: 4px 10px;
}

.group-title {
    border-bottom: 3px double #cdcdcd;
}

.group-box {
    width: 100%;
}

.group-item {
    display: inline-block;
    padding-right: 10px;
    min-width: 100px;
}
</style>